#ifndef OWN_THUNK_BASE_H_080325
#define OWN_THUNK_BASE_H_080325

#include <stdint.h>
//#include <boost/static_assert.hpp>

#include <Thunk/MachineCodeMacro.h>

namespace Thunk
{
	typedef uint8_t		byte;
	typedef uint16_t	word;
	typedef int32_t		dword;
	typedef const void*	dword_ptr;

	//BOOST_STATIC_ASSERT(sizeof(byte)==1);
	//BOOST_STATIC_ASSERT(sizeof(word)==2);
	//BOOST_STATIC_ASSERT(sizeof(dword)==4);
	//BOOST_STATIC_ASSERT(sizeof(dword_ptr)==4);

#pragma pack ( push , 1)
	typedef struct int48
	{
		dword	address;
		word	selector;
	} int48;
#pragma pack ( pop )

	class Helper
	{
		friend class ThisToStd;
		friend class ThisToCdecl;
		friend class StdToStd;
		friend class CdeclToCdecl;

	public:
		template<typename Pointer>
		static int PointerToInt32(Pointer pointer);

	private:
		template<typename dst_type,typename src_type>
		static dst_type pointer_cast(src_type src);

		template<typename dst_type,typename src_type>
		static dst_type union_cast(src_type src);

		static void SetTransferDST(dword_ptr src,dword dst);
		static dword GetTransferDST(dword_ptr src);

		static void FlushInstructionCache(const void*Instructions,unsigned long size);

		static void ReviseVirtualProtect(void*Address,unsigned long size);
	};
	
	template<typename Pointer>
	int Helper::PointerToInt32(Pointer pointer)
	{
		return pointer_cast<int>(pointer);
	}

	template<typename dst_type,typename src_type>
	dst_type Helper::pointer_cast(src_type src)
	{
		return *static_cast<dst_type*>( static_cast<void*>(&src) );
	}

	template<typename dst_type,typename src_type>
	dst_type Helper::union_cast(src_type src)
	{
		union {
			src_type src;
			dst_type dst;
		} u = {src};
		return u.dst;
	}

}

#endif	//#ifndef OWN_THUNK_BASE_H_080325
